using System;
using System.Collections.Generic;
using UnityEngine;
using Yoozoo.Framework.Core;

namespace Yoozoo.Gameplay.City
{
    public class GameObjectPoolManager : SingletonMono<GameObjectPoolManager>
    {
        // 对象池 <path, GameObjectPool>
        private Dictionary<string, GameObjectPool> _ObjectPools = new Dictionary<string, GameObjectPool>();

        /// <summary>
        /// 预加载对象池
        /// </summary>
        /// <param name="path"></param>
        /// <param name="callback"></param>
        public void Preload(string path, Action callback)
        {
            GameObjectPool pool = getOrCreateObjectPool(path);
            pool.Pop(go =>
            {
                Push(path, go);
                callback?.Invoke();
            }, false);
        }

        /// <summary>
        /// 销毁对象池
        /// </summary>
        /// <param name="path"></param>
        public void Destroy(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return;
            }
            GameObjectPool pool;
            if (this._ObjectPools.TryGetValue(path, out pool))
            {
                this._ObjectPools.Remove(path);
                // 销毁对象池
                pool.Dispose();
            }
        }

        /// <summary>
        /// 弹出空闲对象
        /// </summary>
        /// <param name="path"></param>
        /// <param name="callback"></param>
        public void Pop(string path, Action<GameObject> callback, bool autoActive = true)
        {
            GameObjectPool pool = getOrCreateObjectPool(path);
            pool.Pop(callback, autoActive);
        }

        /// <summary>
        /// 回收对象
        /// </summary>
        /// <param name="path"></param>
        /// <param name="go"></param>
        public void Push(string path, GameObject go)
        {
            if (string.IsNullOrEmpty(path))
            {
                GameObject.Destroy(go);
                return;
            }
            
            GameObjectPool pool = getOrCreateObjectPool(path);
            pool.Push(go);
        }

        // 创建对象池
        GameObjectPool getOrCreateObjectPool(string path)
        {
            GameObjectPool pool;
            if (!this._ObjectPools.TryGetValue(path, out pool))
            {
                // 创建对象池
                Transform poolNode = createPoolNode(path);
                pool = new GameObjectPool(poolNode, path);
                this._ObjectPools.Add(path, pool);
            }

            return pool;
        }
        Transform createPoolNode(string name)
        {
            GameObject nodeObject = new GameObject(name);
            Transform nodeTransform = nodeObject.transform;
            nodeTransform.parent = this.transform;
            return nodeTransform;
        }
    }
}
